package com.sina.microblog.ut.cases
{
	import com.sina.microblog.MicroBlog;
	import com.sina.microblog.data.MicroBlogProfileUpdateParams;
	import com.sina.microblog.events.MicroBlogErrorEvent;
	import com.sina.microblog.events.MicroBlogEvent;
	import com.sina.microblog.ut.utils.AssertResult;
	import com.sina.microblog.ut.utils.ResultDataUtils;
	import com.sina.microblog.ut.utils.URLRequestChecker;
	import com.sina.microblog.ut.utils.URLRequestParameters;
	import com.sina.microblog.utils.StringEncoders;
	import com.ut.nm_test_internal;
	
	import flash.net.URLRequest;
	import flash.net.URLRequestMethod;
	import flash.net.URLVariables;
	import flash.utils.ByteArray;
	
	import org.flexunit.asserts.assertEquals;
	import org.flexunit.asserts.assertNull;
	import org.flexunit.asserts.assertTrue;
	import org.flexunit.async.Async;
	
	use namespace nm_test_internal;
	[RunWith("org.flexunit.experimental.theories.Theories")]
	public class AccountTest
	{
		private static const VERIFY_CREDENTIALS_URL_BASE:String = "http://api.t.sina.com.cn/account/verify_credentials.xml";
		private static const RATE_LIMITS_URL_BASE:String = "http://api.t.sina.com.cn/account/rate_limit_status.xml";
		private static const END_SESSION_URL_BASE:String = "http://api.t.sina.com.cn/account/end_session.xml";
		private static const UPDATE_PROFILE_IMAGE:String = "http://api.t.sina.com.cn/account/update_profile_image.xml";
		private static const UPDATE_PROFILE_URL_BASE:String = "http://api.t.sina.com.cn/account/update_profile.xml";
		private static const PROVINCES_URL_BASE:String = "http://api.t.sina.com.cn/provinces.xml";
		
		private static const TIME_OUT:uint = 50;	
		private static var mb:MicroBlog;
		private static var tester:String = "tester";
		private static var oriUserScreenName:String = "测试=a&b";
		private static var encodedUserScreenName:String = StringEncoders.urlEncodeUtf8String(oriUserScreenName);
		private static var testMessage:String = StringEncoders.urlEncodeUtf8String("测试消息，&消息bca==");
		private static var testMessageID:uint = 132323;
		
		[DataPoints]
		[ArrayElementType("String")]
		public static var names:Array = [null, "测试&tester1"];
		
		public function AccountTest()
		{
		}
		
		[BeforeClass]
		public static function setUp():void
		{
			if ( null == mb )
			{
				mb = new MicroBlog();
			}
		}
		
		//Test Verify_credentials.
		[Test]
		public function testVerify():void
		{
			mb.addEventListener( MicroBlogEvent.VERIFY_CREDENTIALS_RESULT, AssertResult.assertUser, false, 0, true);
			
			var params:URLRequestParameters = new URLRequestParameters(mb.source);
			var url:String = VERIFY_CREDENTIALS_URL_BASE + params.toGetString();
			
			
			var req:URLRequest = new URLRequest(url);
			mb.login("tester@test.com", "tester");
			URLRequestChecker.check(mb, req, ResultDataUtils.user);			
			
		}
		[Test]
		public function testVerifyFail():void
		{
			mb.addEventListener( MicroBlogErrorEvent.VERIFY_CREDENTIALS_ERROR, AssertResult.assertError, false, 0, true);
			
			var params:URLRequestParameters = new URLRequestParameters(mb.source);
			var url:String = VERIFY_CREDENTIALS_URL_BASE + params.toGetString();
			
			
			var req:URLRequest = new URLRequest(url);
			mb.login("tester@test.com", "tester");
			URLRequestChecker.check(mb, req, ResultDataUtils.error);
		}
		[Test]
		public function testVerifyNotInvoked():void
		{
			var params:URLRequestParameters = new URLRequestParameters(mb.source);
			var url:String = VERIFY_CREDENTIALS_URL_BASE + params.toGetString();
			mb.login("tester@test.com", null);
			var req:URLRequest = mb.lastRequest;
			if ( req )
			{
				if ( req.url != VERIFY_CREDENTIALS_URL_BASE )
				{
					assertTrue(true);
				} else
				{
					assertTrue(false);
				}
			} else
			{
				assertTrue(true);
			}
			
		}
		
		//Test Rate limits status.
		[Test]
		public function testRateLimits():void
		{
			mb.addEventListener(MicroBlogEvent.GET_RATE_LIMIT_STATUS_RESULT, AssertResult.assertRateLimits, false, 0, true);
			
			var params:URLRequestParameters = new URLRequestParameters(mb.source);
			var url:String = RATE_LIMITS_URL_BASE + params.toGetString();
			
			
			var req:URLRequest = new URLRequest(url);
			mb.getRateLimitInfo();
			URLRequestChecker.check(mb, req, ResultDataUtils.limits);			
			
		}
		[Test]
		public function testRateLimitsFail():void
		{
			mb.addEventListener(MicroBlogErrorEvent.GET_RATE_LIMIT_STATUS_ERROR, AssertResult.assertError, false, 0, true);
			
			var params:URLRequestParameters = new URLRequestParameters(mb.source);
			var url:String = RATE_LIMITS_URL_BASE + params.toGetString();
			
			
			var req:URLRequest = new URLRequest(url);
			mb.getRateLimitInfo();
			URLRequestChecker.check(mb, req, ResultDataUtils.error);
		}
		
		//Test End Session.
		[Test]
		public function testEndSession():void
		{
			mb.addEventListener(MicroBlogEvent.LOGOUT_RESULT, AssertResult.assertUser, false, 0, true);
			
			var params:URLRequestParameters = new URLRequestParameters(mb.source);
			var url:String = END_SESSION_URL_BASE;
			
			
			var req:URLRequest = new URLRequest(url);
			req.data = params.toPostData();
			req.method = URLRequestMethod.POST;
			mb.logout();
			URLRequestChecker.check(mb, req, ResultDataUtils.user);			
			
		}
		[Test]
		public function testEndSessionFail():void
		{
			mb.addEventListener(MicroBlogErrorEvent.LOGOUT_ERROR, AssertResult.assertError, false, 0, true);
			var params:URLRequestParameters = new URLRequestParameters(mb.source);
			var url:String = END_SESSION_URL_BASE;
			
			
			var req:URLRequest = new URLRequest(url);
			req.data = params.toPostData();
			req.method = URLRequestMethod.POST;
			
			mb.logout();
			URLRequestChecker.check(mb, req, ResultDataUtils.error);
		}
		
		//Test update profile image.
		[Test]
		public function testUpdateProfileImage():void
		{
			mb.addEventListener(MicroBlogEvent.UPDATE_PROFILE_IMAGE_RESULT, AssertResult.assertUser, false, 0, true);
			
			var ba:ByteArray = new ByteArray();
			ba.writeUTFBytes("Test Bytes");
			ba.position = 0;
			
			var req:URLRequest = new URLRequest(UPDATE_PROFILE_IMAGE);
			req.method = URLRequestMethod.POST;
			
			mb.updateProfileImage(ba,"test.jpg");
			URLRequestChecker.check(mb, req, ResultDataUtils.user);			
			
		}
		[Test]
		public function testUpdateProfileImageFail():void
		{
			mb.addEventListener(MicroBlogErrorEvent.UPDATE_PROFILE_IMAGE_ERROR, AssertResult.assertError, false, 0, true);
			
			var ba:ByteArray = new ByteArray();
			ba.writeUTFBytes("Test Bytes");
			ba.position = 0;
			
			var req:URLRequest = new URLRequest(UPDATE_PROFILE_IMAGE);
			req.method = URLRequestMethod.POST;
			mb.updateProfileImage(ba, "test.jpg");
			URLRequestChecker.check(mb, req, ResultDataUtils.error);
		}
		[Test]
		public function testUpdateProfileImageRequest():void
		{	
			
			var req:URLRequest = new URLRequest(UPDATE_PROFILE_IMAGE);
			req.method = URLRequestMethod.POST;
			var destReq:URLRequest = mb.getUpdateProfileImageRequest(); 
			var params:URLRequestParameters = new URLRequestParameters(mb.source);
			req.data = params.toPostData();
			
			assertEquals(req.url, destReq.url);
			assertEquals(req.method, destReq.method);
			assertEquals(req.data.source, destReq.data.source);
			
		}
		
		//Test update profile.
		[Test]
		public function testUpdateProfile():void
		{
			mb.addEventListener(MicroBlogEvent.UPDATE_PROFILE_RESULT, AssertResult.assertUser, false, 0, true);
			
			var params:URLRequestParameters = new URLRequestParameters(mb.source);
			
			var up:MicroBlogProfileUpdateParams = new MicroBlogProfileUpdateParams();
			up.name = names[1];
			
			var req:URLRequest = new URLRequest(UPDATE_PROFILE_URL_BASE);
			req.method = URLRequestMethod.POST;
			req.data = params.toPostData();
			req.data.name = StringEncoders.urlEncodeUtf8String(names[1]);
			mb.updateProfile(up);
			URLRequestChecker.check(mb, req, ResultDataUtils.user);			
			
		}
		[Test]
		public function testUpdateProfileFail():void
		{
			mb.addEventListener(MicroBlogErrorEvent.UPDATE_PROFILE_ERROR, AssertResult.assertError, false, 0, true);
			
			var params:URLRequestParameters = new URLRequestParameters(mb.source);
			
			var up:MicroBlogProfileUpdateParams = new MicroBlogProfileUpdateParams();
			up.name = names[1];
			up.gender = null;
			
			
			var req:URLRequest = new URLRequest(UPDATE_PROFILE_URL_BASE);
			req.method = URLRequestMethod.POST;
			req.data = params.toPostData();
			req.data.name = StringEncoders.urlEncodeUtf8String(names[1]);
			mb.updateProfile(up);
			URLRequestChecker.check(mb, req, ResultDataUtils.error);
		}
		[Test]
		public function testUpdateProfileWithNullParam():void
		{
			mb.lastRequest = null;
			
			mb.updateProfile(null);
			assertNull(mb.lastRequest);
			
		}
		[Test]
		public function testUpdateProfileWithEmptyParam():void
		{
			mb.lastRequest = null;
			var up:MicroBlogProfileUpdateParams = new MicroBlogProfileUpdateParams();
			
			mb.updateProfile(up);
			assertNull(mb.lastRequest);
			
		}
		[Theory]
		public function testUpdateProfileTheory(name:String, qq:String, msn:String, province:String, city:String, description:String, url:String, location:String):void
		{
			var params:URLRequestParameters = new URLRequestParameters(mb.source);
			var up:MicroBlogProfileUpdateParams = new MicroBlogProfileUpdateParams();
			var postData:URLVariables = params.toPostData();
			
			postData.gender=StringEncoders.urlEncodeUtf8String("男");
			up.gender = "男";
			if ( name )
			{
				postData.name=StringEncoders.urlEncodeUtf8String(name);
				up.name = name;
			}
			
			if ( qq)
			{
				postData.qq=StringEncoders.urlEncodeUtf8String(qq);
				up.qq = qq;
			}
			
			if ( msn )
			{
				postData.msn=StringEncoders.urlEncodeUtf8String(msn);
				up.msn = msn;
			}
			if (province)
			{
				postData.province=StringEncoders.urlEncodeUtf8String(province);
				up.province = province;
			}
			if (city)
			{
				postData.city=StringEncoders.urlEncodeUtf8String(city);
				up.city = city;
			}
			if ( description )
			{
				postData.description=StringEncoders.urlEncodeUtf8String(description);
				up.description = description;
			}
			if ( url )
			{
				postData.url=StringEncoders.urlEncodeUtf8String(url) ;
				up.url = url;
			}
			if (location)
			{
				postData.location=StringEncoders.urlEncodeUtf8String(location);
				up.location = location;
			}
			var req:URLRequest = new URLRequest(UPDATE_PROFILE_URL_BASE);
			req.method = URLRequestMethod.POST;
			req.data = params.toPostData();
			mb.updateProfile(up);
			URLRequestChecker.check(mb, req, null);
		}
		
		//Test Provinces.
		[Test(async,timeout="20000")]
		public function testProvinces():void
		{
			Async.handleEvent(this, mb, MicroBlogEvent.LOAD_PROVINCE_CITY_ID_LIST_RESULT, AssertResult.assertProvinces, TIME_OUT);
			
			var params:URLRequestParameters = new URLRequestParameters(mb.source);
			
			var req:URLRequest = new URLRequest(PROVINCES_URL_BASE+params.toGetString());
			
			mb.loadProvinceCityIDList();
			URLRequestChecker.check(mb, req, ResultDataUtils.provinces);			
			
		}
		[Test(async,timeout="20000")]
		public function testProvincesFail():void
		{
			Async.handleEvent(this, mb, MicroBlogErrorEvent.LOAD_PROVINCE_CITY_ID_LIST_ERROR, AssertResult.assertError, TIME_OUT);
			var params:URLRequestParameters = new URLRequestParameters(mb.source);
			
			var req:URLRequest = new URLRequest(PROVINCES_URL_BASE+params.toGetString());
			mb.loadProvinceCityIDList();
			URLRequestChecker.check(mb, req, ResultDataUtils.error);
		}
		
	}
}